package logger

import (
	"fmt"
	"os"
	"path/filepath"
	"time"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
)

/**
* 日志配置说明
* Info: 一般信息
* Error: 错误信息
* Debug: 调试信息
* Warn: 警告信息
* Fatal: 致命错误
* WithFields: 添加字段
* Field: 创建日志字段
* String: 创建字符串字段
* Int: 创建整数字段
* ErrorField: 创建错误字段
* Duration: 创建持续时间字段
* 日志文件路径: logs/info.log 和 logs/error.log
* 日志文件大小限制: 100MB
* 日志文件保留时间: 30天
* 日志文件备份数量: 30个
* 日志文件压缩: 启用
* 日志输出格式: JSON
* 日志输出级别: 根据配置文件设置
* 日志输出位置: 控制台和文件
**/

var Log *zap.Logger

// LogConfig 日志配置
type LogConfig struct {
	EnableConsole bool // 是否启用控制台输出
	EnableFile    bool // 是否启用文件输出
}

// Init 初始化日志
func Init(config ...LogConfig) error {
	cfg := LogConfig{
		EnableConsole: true,  // 默认启用控制台输出
		EnableFile:    false, // 默认禁用文件输出
	}

	if len(config) > 0 {
		cfg = config[0]
	}

	// 设置日志输出格式
	encoderConfig := zapcore.EncoderConfig{
		TimeKey:        "time",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		MessageKey:     "msg",
		StacktraceKey:  "stacktrace",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.LowercaseLevelEncoder,
		EncodeTime:     zapcore.ISO8601TimeEncoder,
		EncodeDuration: zapcore.SecondsDurationEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder,
	}

	// 创建核心列表
	var cores []zapcore.Core

	// 添加控制台输出
	if cfg.EnableConsole {
		consoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
		consoleCore := zapcore.NewCore(
			consoleEncoder,
			zapcore.AddSync(os.Stdout),
			zapcore.DebugLevel,
		)
		cores = append(cores, consoleCore)
	}

	// 添加文件输出
	if cfg.EnableFile {
		// 创建日志目录
		logDir := "logs"
		if err := os.MkdirAll(logDir, 0755); err != nil {
			return fmt.Errorf("创建日志目录失败: %v", err)
		}

		// 设置日志轮转
		infoWriter := &lumberjack.Logger{
			Filename:   filepath.Join(logDir, "info.log"),
			MaxSize:    100,
			MaxBackups: 30,
			MaxAge:     30,
			Compress:   true,
		}

		errorWriter := &lumberjack.Logger{
			Filename:   filepath.Join(logDir, "error.log"),
			MaxSize:    100,
			MaxBackups: 30,
			MaxAge:     30,
			Compress:   true,
		}

		// 添加文件输出核心
		cores = append(cores,
			zapcore.NewCore(
				zapcore.NewJSONEncoder(encoderConfig),
				zapcore.AddSync(infoWriter),
				zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
					return lvl < zapcore.ErrorLevel
				}),
			),
			zapcore.NewCore(
				zapcore.NewJSONEncoder(encoderConfig),
				zapcore.AddSync(errorWriter),
				zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
					return lvl >= zapcore.ErrorLevel
				}),
			),
		)
	}

	// 创建日志实例
	core := zapcore.NewTee(cores...)
	Log = zap.New(core,
		zap.AddCaller(),
		zap.AddCallerSkip(1),
		zap.AddStacktrace(zapcore.ErrorLevel),
	)

	return nil
}

// Info 记录信息日志
func Info(msg string, fields ...zap.Field) {
	Log.Info(msg, fields...)
}

// Error 记录错误日志
func Error(msg string, fields ...zap.Field) {
	Log.Error(msg, fields...)
}

// Debug 记录调试日志
func Debug(msg string, fields ...zap.Field) {
	Log.Debug(msg, fields...)
}

// Warn 记录警告日志
func Warn(msg string, fields ...zap.Field) {
	Log.Warn(msg, fields...)
}

// Fatal 记录致命错误日志
func Fatal(msg string, fields ...zap.Field) {
	Log.Fatal(msg, fields...)
}

// WithFields 添加字段
func WithFields(fields ...zap.Field) *zap.Logger {
	return Log.With(fields...)
}

// Field 创建日志字段
func Field(key string, value interface{}) zap.Field {
	return zap.Any(key, value)
}

// String 创建字符串字段
func String(key string, value string) zap.Field {
	return zap.String(key, value)
}

// Int 创建整数字段
func Int(key string, value int) zap.Field {
	return zap.Int(key, value)
}

// Error 创建错误字段
func ErrorField(err error) zap.Field {
	return zap.Error(err)
}

// Duration 创建持续时间字段
func Duration(key string, value time.Duration) zap.Field {
	return zap.Duration(key, value)
}
